package com.heima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.bean.*;
import com.heima.common.PageParam;
import com.heima.dao.OrderDao;
import com.heima.dto.OrdersDto;
import com.heima.service.*;
import com.heima.utils.BaseContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@Transactional
public class OrderServiceImpl implements OrderService {


    @Autowired
    private UserService userService;
    @Autowired
    private OrderDao orderDao;

    @Autowired
    private HttpSession session;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private OrderDetailService orderDetailService;

    /**
     * 提交订单
     * 1. 提交订单其实是一种添加的行为，但是它要往两张表里面添加数据： orders 和 order_detail
     * <p>
     * 2. 先添加 orders 表、
     * 2.1 才能得到订单的id主键
     * <p>
     * 3. 再添加order_detail 表
     * 3.1 给订单详情设置 订单id主键
     *
     * @param order
     * @return
     */
    @Override
    public int add(Orders order) {
        //1、先提交订单表
        //1.1 设置订单号
        // 获取用户信息
        User user = (User) session.getAttribute("user");
        //获取地址信息

        AddressBook addressBook = addressBookService.getById(order.getAddressBookId());
        System.out.println("addressBook ========================= " + addressBook);
        order.setNumber(UUID.randomUUID().toString().replace("-", ""));
        //1.2 设置状态值 : 1 : 未付款，2： 已付款，待派送 ...
        order.setStatus(1);
        //1.3 设置用户id
        order.setUserId(user.getId());
        //1.4 设置地址id【页面提供了，不需要设置】
        //1.5 设置下单时间
        order.setOrderTime(LocalDateTime.now());
        //1.6 设置支付时间
        order.setCheckoutTime(LocalDateTime.now());
        //1.7 设置支付方式【页面提供了，不需要设置】
        //1.8 设置总金额 【页面提供了，不需要设置】
        //1.9 设置备注【页面提供了，不需要设置】
        //1.10 设置收货电话
        order.setPhone(addressBook.getPhone());
        //1.11 设置收货地址
        String address = (addressBook.getProvinceName() != null ? addressBook.getProvinceName() : "") +
                (addressBook.getCityName() != null ? addressBook.getCityName() : "") +
                (addressBook.getDistrictName() != null ? addressBook.getDistrictName() : "") +
                (addressBook.getDetail() != null ? addressBook.getDetail() : "");
        order.setAddress(address);
        //1.12 设置下单的用户名称
        order.setUserName(user.getName());
        //1.13 设置收货人名称
        order.setConsignee(addressBook.getConsignee());

        //执行添加
        int row = orderDao.insert(order);

        //2. 再添加订单详情表 :: 详情表的数据，页面没有提供，购买的详细内容，其实就是购物车的内容。
        //订单添加成功再添加订单详情表
        if (row > 0) {
            //获取当前用户的购物车数据
            List<ShoppingCart> shoppingCarts = shoppingCartService.list();
            if (shoppingCarts.size() > 0) {
                int row2 = 0;
                //遍历每一个购物车数据
                for (ShoppingCart shoppingCart : shoppingCarts) {
                    //每遍历一次就构建一个订单详情对象
                    OrderDetail orderDetail = new OrderDetail();

                    //将购物车的数据拷贝到订单详情表里面去
                    BeanUtils.copyProperties(shoppingCart, orderDetail);

                    //设置订单id
                    orderDetail.setOrderId(order.getId());

                    //添加到订单详情表
                    row2 += orderDetailService.add(orderDetail);
                }
                if (row2 == shoppingCarts.size()) {
                    //添加成功，清空购物车
                    shoppingCartService.clean();
                    return 1;
                } else {
                    //添加失败
                    return 0;
                }
            }
        }
        //添加失败
        return row;
    }

    @Override
    public IPage<Orders> getUserPage(PageParam pageParam) {
        IPage<Orders> page = new Page<>(pageParam.getPage(), pageParam.getPageSize());
        LambdaQueryWrapper<Orders> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Orders::getUserId, BaseContext.getCurrentId());
        return orderDao.selectPage(page, lqw);

    }

    @Override
    public IPage<OrdersDto> getPage(PageParam pageParam) {
        IPage<OrdersDto> ordersDtoIPage = new Page<>();


        IPage<Orders> page = new Page<>(pageParam.getPage(), pageParam.getPageSize());
        LambdaQueryWrapper<Orders> lqw = new LambdaQueryWrapper<>();
        lqw.like(pageParam.getNumber() != null, Orders::getNumber, pageParam.getNumber());
        lqw.between(pageParam.getBeginTime() != null, Orders::getOrderTime, pageParam.getBeginTime(), pageParam.getEndTime());
        IPage<Orders> ordersIPage = orderDao.selectPage(page, lqw);

        ordersDtoIPage.setTotal(ordersIPage.getTotal());

        List<Orders> orders = ordersIPage.getRecords();
        List<OrdersDto> ordersDtoList = orders.stream().map(order -> {
            OrdersDto ordersDto = new OrdersDto();
            User user = userService.findById(order.getUserId());
            BeanUtils.copyProperties(order, ordersDto);
            ordersDto.setUserName(user.getName());
            return ordersDto;
        }).collect(Collectors.toList());

        ordersDtoIPage.setRecords(ordersDtoList);
        return ordersDtoIPage;
    }

    @Override
    public int updateStatus(Orders orders) {
        return orderDao.updateById(orders);
    }

    public Orders prepareOrder(Orders orders, User user) {

        User userById = userService.findById(user.getId());

        orders.setNumber(UUID.randomUUID().toString().replace("-", ""));
        orders.setStatus(2);
        orders.setUserId(user.getId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setCheckoutTime(LocalDateTime.now());
        orders.setPhone(user.getPhone());

        System.out.println(orders.getAddressBookId());
        AddressBook addressBook = addressBookService.getById(orders.getAddressBookId());
        String address = (addressBook.getProvinceName() != null ? addressBook.getProvinceName() : "") + (addressBook.getCityName() != null ? addressBook.getCityName() : "") +
                (addressBook.getDistrictName() != null ? addressBook.getDistrictName() : "") + (addressBook.getDetail() != null ? addressBook.getDetail() : "");

        orders.setAddress(address);
        orders.setUserName(userById.getName());
        orders.setConsignee(addressBook.getConsignee());
        return orders;
    }


}
